﻿
using Microsoft.AspNetCore.Mvc.ModelBinding;

using Newtonsoft.Json.Linq;

using System;
using System.Reflection;
using System.Threading.Tasks;

using Utils;

namespace Microsoft.AspNetCore.Mvc
{
    [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
    public class TokenAttribute : Microsoft.AspNetCore.Mvc.ModelBinderAttribute
    {
        public TokenAttribute() : base(typeof(DefaultModelBinderProvider))
        {

        }


    }
    class DefaultModelBinderProvider : IModelBinder
    {
        public Task BindModelAsync(ModelBindingContext bindingContext)
        {


            if (bindingContext.ActionContext.HttpContext.User.Identity is AuthIdentity token)
            {
                if (bindingContext.ModelType.IsInstanceOfType(token))
                {
                    bindingContext.Result = ModelBindingResult.Success(token);
                    return Task.CompletedTask;
                }
                else
                {
                    var pv = token.GetType().GetProperty(bindingContext.FieldName, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase);
                    if (pv != null)
                    {
                        object value = pv.GetValue(token, null);
                        if (bindingContext.ModelType.IsInstanceOfType(value))
                        {
                            bindingContext.Result = ModelBindingResult.Success(value);
                            return Task.CompletedTask;
                        }
                        else
                        {
                            try
                            {
                                bindingContext.Result = ModelBindingResult.Success(Convert.ChangeType(value, bindingContext.ModelType));
                                return Task.CompletedTask;
                            }
                            catch (Exception)
                            {

                            }
                        }
                    }
                }
            }

            if (bindingContext.ModelType.IsNullable())
            {
                bindingContext.Result = ModelBindingResult.Success(null);
                return Task.CompletedTask;
            }
            bindingContext.Result = ModelBindingResult.Failed();
            return Task.FromException(Error.CustomError(ErrorType.AuthorizationError));
        }
    }
}
